package com.ldn.controller.api;

import cn.hutool.captcha.AbstractCaptcha;
import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.generator.MathGenerator;
import cn.hutool.captcha.generator.RandomGenerator;
import cn.hutool.core.util.IdUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.ldn.basic.dispose.exception.AppException;
import com.ldn.basic.types.VerificationType;
import com.ldn.basic.utils.cache.HutoolCacheUtils;
import com.ldn.controller.vo.VerificationCodeVo;

/**
 * @author 李大牛家的牛 (scafel@163.com) 
 * @createDate 2024/7/11 - 15:25
 * @description ...
 **/
@Tag(name = "图形验证码", description = "请求验证码相关接口,并将验证码保存到缓存中")
@RestController
@RequestMapping("/api/captcha")
public class CaptchaController {
    private static final int CAPTCHA_WIDTH = 300;
    private static final int CAPTCHA_HEIGHT = 100;
    private static final int CAPTCHA_CODE_LENGTH = 4;
    private static final long CAPTCHA_CODE_TIMEOUT = 5 * 60;


    @Operation(summary = "获取动态图像验证码")
    @GetMapping("/image/gif")
    public VerificationCodeVo getVerificationGifImage() {
        return getVerificationImage(VerificationType.GIF);
    }

    @Operation(summary = "获取四则运算验证码")
    @GetMapping("/image/math")
    public VerificationCodeVo getVerificationMathImage() {
        return getVerificationImage(VerificationType.MATH);
    }

    @Operation(summary = "获取纯数字验证码")
    @GetMapping("/image/number")
    public VerificationCodeVo getVerificationNumberImage() {
        return getVerificationImage(VerificationType.NUMBER);
    }

    /**
     * @author 李大牛家的牛(scafel@163.com)
     * @description 根据验证码类型获取验证码信息
     * @title getVerificationImage
     * @param type: 调用类型
     * @return VerificationCodeVo 返回验证码信息
     **/
    private VerificationCodeVo getVerificationImage(VerificationType type) {
        VerificationCodeVo dto = new VerificationCodeVo();
        AbstractCaptcha captcha = null;
        // 使用工厂模式创建验证码对象
        captcha = createCaptcha(type);
        if (captcha != null) {
            // 输出到页面
            String image = captcha.getImageBase64Data();
            String code = IdUtil.simpleUUID();
            // 此处需要保存验证码到缓存中
            HutoolCacheUtils.setEx(code, captcha.getCode(), CAPTCHA_CODE_TIMEOUT);
            dto.setImg(image);
            dto.setImgCode(code);
            dto.setImgTimeout(CAPTCHA_CODE_TIMEOUT);
        } else {
            throw new AppException("验证码类型错误");
        }
        return dto;
    }

    /**
     * @author 李大牛家的牛(scafel@163.com)
     * @description 根据验证类型和验证码对象创建验证码
     * @title createCaptcha
     * @param type: 验证类型
     * @return cn.hutool.captcha.AbstractCaptcha 创建的验证码对象
     **/
    private AbstractCaptcha createCaptcha(VerificationType type) {
        AbstractCaptcha captcha = null;
        switch (type) {
            case MATH:
                captcha = CaptchaUtil.createShearCaptcha(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, CAPTCHA_CODE_LENGTH, 4);
                captcha.setGenerator(new MathGenerator());
                break;
            case NUMBER:
                RandomGenerator randomGenerator = new RandomGenerator("0123456789", CAPTCHA_CODE_LENGTH);
                captcha = CaptchaUtil.createLineCaptcha(CAPTCHA_WIDTH, CAPTCHA_HEIGHT);
                captcha.setGenerator(randomGenerator);
                break;
            case GIF:
            default:
                captcha = CaptchaUtil.createGifCaptcha(CAPTCHA_WIDTH, CAPTCHA_HEIGHT, CAPTCHA_CODE_LENGTH);
                break;
        }
        return captcha;
    }

}
